package com.yunshipei.core.manager;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;

import com.yunshipei.core.R;
import com.yunshipei.core.common.XCloudException;
import com.yunshipei.core.common.db.DBManager;
import com.yunshipei.core.model.ConfigInfo;
import com.yunshipei.core.model.UWAApplication;
import com.yunshipei.core.net.DownloadApi;
import com.yunshipei.core.net.EnterClient;
import com.yunshipei.core.utils.FileUtils;
import com.yunshipei.core.utils.StringUtils;

import org.reactivestreams.Publisher;

import java.io.File;
import java.util.List;

import io.reactivex.Flowable;
import io.reactivex.functions.Function;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

public class UWAPkgHandler {

    static final String UWA_INFO_TAB_NAME = "universal_web_app_info";
    static final String UWA_APP_ID = "appId";
    static final String UWA_PKG_NAME = "pkg_name";
    private static final String UWA_VERSION = "version";

    private Context context;
    private String rootPath;

    public UWAPkgHandler(Context context) {
        this.context = context;
        this.rootPath = context.getFilesDir().getPath() + File.separator + "uwa";
    }

    public Flowable<String> start(String url) {
        return Flowable.just(url).flatMap(new Function<String, Publisher<String>>() {
            @Override
            public Publisher<String> apply(String url) throws Exception {
                if (!url.startsWith("enterplorer://universal.web.app/")) {
                    return Flowable.error(new XCloudException(context.getString(R.string.not_universal_app)));
                }
                Uri uri = Uri.parse(url);
                String pkgName = "";
                if (uri != null) {
                    List<String> ps = uri.getPathSegments();
                    if (ps != null && ps.size() > 0) {
                        pkgName = ps.get(0);
                    }
                }
                if (TextUtils.isEmpty(pkgName)) {
                    return Flowable.error(new XCloudException(context.getString(R.string.error_uwa_url)));
                }
                ConfigInfo configInfo = XCloud2Map.getInstance().getConfigInfo();
                List<UWAApplication> uwaApplications = configInfo.getUWAApplications();
                if (uwaApplications == null || uwaApplications.size() == 0) {
                    return Flowable.error(new XCloudException(context.getString(R.string.no_uwa_download_cfg)));
                }
                UWAApplication uwaApplication = null;
                for (UWAApplication uwa : uwaApplications) {
                    String name = StringUtils.getZipPkgDownloadUrlFileName(uwa.getDownloadUrl());
                    if (pkgName.equals(name)) {
                        uwaApplication = uwa;
                        break;
                    }
                }
                if (uwaApplication == null) {
                    return Flowable.error(new XCloudException(context.getString(R.string.no_this_uwa_cfg)));
                }
                String eAppVersion = "";
                DBManager dbManager = DBManager.getInstance();
                SQLiteDatabase db = dbManager.openDB(context);
                Cursor cursor = db.query(UWA_INFO_TAB_NAME, new String[]{UWA_VERSION}, UWA_APP_ID + "=?", new String[]{uwaApplication.getAppId()}, null, null, null);
                if (cursor.moveToNext()) {
                    eAppVersion = cursor.getString(0);
                }
                cursor.close();
                dbManager.closeDB();
                //uwa file对象
                File file = new File(rootPath + File.separator + pkgName);
                boolean exist = file.exists() && file.listFiles() != null;
                if (!TextUtils.isEmpty(eAppVersion) && eAppVersion.equals(uwaApplication.getVersion()) && exist) {
                    return Flowable.just("file://" + rootPath + File.separator + pkgName + File.separator + "index.html");
                }
                return downloadUWA(uwaApplication);
            }
        });
    }

    private Flowable<String> downloadUWA(final UWAApplication uwaApplication) {
        final String pkgName = StringUtils.getZipPkgDownloadUrlFileName(uwaApplication.getDownloadUrl());
        final ConfigInfo configInfo = XCloud2Map.getInstance().getConfigInfo();
        String managerServer = configInfo.getUrl();
        OkHttpClient client = EnterClient.getInstances().getManagerClient();
        DownloadApi downloadApi = new Retrofit.Builder().client(client).baseUrl(managerServer).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build().create(DownloadApi.class);
        return downloadApi.get(uwaApplication.getDownloadUrl()).flatMap(new Function<Response<ResponseBody>, Publisher<Boolean>>() {
            @Override
            public Publisher<Boolean> apply(Response<ResponseBody> responseBodyResponse) throws Exception {
                int code = responseBodyResponse.code();
                if (200 != code) {
                    return Flowable.error(new XCloudException(String.format(context.getString(R.string.uwa_download_failed) + responseBodyResponse.message(), pkgName)));
                }
                File tempFile = new File(rootPath + File.separator + pkgName + "_temp");
                if (!tempFile.exists()) {
                    boolean b = tempFile.mkdirs();
                } else {
                    FileUtils.deleteFileHoldPath(tempFile.getPath());
                }
                boolean unZip = FileUtils.unZipStream(responseBodyResponse.body().byteStream(), tempFile.getPath());
                if (unZip) {
                    File newFile = new File(rootPath + File.separator + pkgName);
                    FileUtils.deletePathReal(newFile.getPath());
                    boolean reName = tempFile.renameTo(newFile);
                    if (reName) {
                        return Flowable.just(true);
                    } else {
                        return Flowable.error(new XCloudException(String.format(context.getString(R.string.uwa_rename_failed), pkgName)));
                    }
                } else {
                    return Flowable.error(new XCloudException(String.format(context.getString(R.string.uwa_unzip_failed), pkgName)));
                }
            }
        }).flatMap(new Function<Boolean, Publisher<String>>() {
            @Override
            public Publisher<String> apply(Boolean aBoolean) throws Exception {
                //保存小程序配置信息
                DBManager dbManager = DBManager.getInstance();
                SQLiteDatabase db = dbManager.openDB(context);
                db.beginTransaction();
                String appId = uwaApplication.getAppId();
                android.content.ContentValues contentValues = new android.content.ContentValues();
                contentValues.put(UWA_APP_ID, appId);
                contentValues.put(UWA_VERSION, uwaApplication.getVersion());
                contentValues.put(UWA_PKG_NAME, pkgName);
                Cursor c = db.query(UWA_INFO_TAB_NAME, new String[]{UWA_VERSION}, UWA_APP_ID + "=?", new String[]{appId}, null, null, null);
                if (c.moveToNext()) {
                    db.update(UWA_INFO_TAB_NAME, contentValues, UWA_APP_ID + "=?", new String[]{appId});
                } else {
                    db.insert(UWA_INFO_TAB_NAME, null, contentValues);
                }
                c.close();
                db.setTransactionSuccessful();
                db.endTransaction();
                dbManager.closeDB();
                return Flowable.just("file://" + rootPath + File.separator + pkgName + File.separator + "index.html");
            }
        });
    }
}
